package com.hsq.ndmall.wx.service;

import com.hsq.ndmall.wx.common.StorageProperties;
import com.hsq.ndmall.wx.vo.storage.StorageVo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * @author 黄四清
 * @version 1.0.0
 * @ClassName StorageService.java
 * @Description TODO 对象存储服务
 * @createTime 2021年08月25日 19:2 7:00
 */
@Service
public class StorageService {


    @Autowired
    StorageProperties storageProperties;

    /**
     * 文件上传
     * @param file
     * @return
     */
    public Map putFile(MultipartFile file) {
        Map<String,Object> resultMap=new HashMap<>();
        // 1 初始化用户身份信息（secretId, secretKey）。
        // SECRETID和SECRETKEY请登录访问管理控制台进行查看和管理
        String secretId = storageProperties.getAccessKey();
        String secretKey = storageProperties.getSecretKey();
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2 设置 bucket 的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region(storageProperties.getBucket());
        ClientConfig clientConfig = new ClientConfig(region);
        // 这里建议设置使用 https 协议 binary
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        // 存储桶名称
        String bucketName = storageProperties.getBucketName();
//        List<Bucket> buckets = cosClient.listBuckets();
//        for (Bucket bucketElement : buckets) {
//            bucketName = bucketElement.getName();  // 存储桶名称
//            String bucketLocation = bucketElement.getLocation(); // 所属地域
//            System.out.println("存储桶：：：" + bucketName);
//        }

        // 4、获得上传的文件名
        String oldFileName = file.getOriginalFilename();
        // 5、 生成UUID作为文件头部+自己文件名
        String newFileName = UUID.randomUUID() + oldFileName;
        // 6、获得系统日期
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;
        int day = cal.get(Calendar.DATE);

        File localFile = null;
        try {
            localFile = File.createTempFile("temp",null);
            // 把用户传入的文件转移到临时文件
            file.transferTo(localFile);
            // 指定要上传到 COS 上的路径
            String key = "/"+"img"+"/"+year+"/"+month+"/"+day+"/"+newFileName;
            // 调腾讯api
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            // putObjectRequest.getKey() 获得上传成功的信息
            StorageVo storageVo = new StorageVo();
            // TODO 1、id(文件id)
            storageVo.setId(new Random().nextInt(100));
            // TODO 2、key(文件的唯一索引)
            storageVo.setKey(putObjectRequest.getKey());
            System.out.println(putObjectRequest.getKey());
            // TODO 3、name (文件名)
            storageVo.setName(oldFileName);
            // TODO 4、type （文件类型）
            storageVo.setType(oldFileName.substring(oldFileName.lastIndexOf(".")));
            // TODO 5、size (文件大小)
            storageVo.setSize(file.getSize());
            // TODO 6、url (文件访问链接）
            URL objectUrl = cosClient.getObjectUrl(bucketName, putObjectRequest.getKey());
            storageVo.setUrl(objectUrl.toString());
            // TODO 8、add_time
            storageVo.setAdd_time(new Date());
            // TODO 9、update_time
            storageVo.setUpdate_time(new Date());
            resultMap.put("data",storageVo);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭客户端(关闭后台线程)
            cosClient.shutdown();
        }
        return resultMap;
    }


    /**
     * 下载文件唯一标识（key）为key的的图片
     * @param key
     * @return
     */
    public Map getFile(String key){
        Map<String,Object> resultMap=new HashMap<>();
        // 初始化永久密钥信息
        // SECRETID和SECRETKEY请登录访问管理控制台进行查看和管理
        String secretId = storageProperties.getAccessKey();
        String secretKey = storageProperties.getSecretKey();
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        Region region = new Region(storageProperties.getBucket());
        ClientConfig clientConfig = new ClientConfig(region);
        // 如果要生成一个使用 https 协议的 URL，则设置此行，推荐设置。
        // clientConfig.setHttpProtocol(HttpProtocol.https);
        // 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        // 存储桶的命名格式为 BucketName-APPID，此处填写的存储桶名称必须为此格式
        String bucketName =storageProperties.getBucketName();
        // 此处的key为对象键，对象键是对象在存储桶内的唯一标识
        GeneratePresignedUrlRequest req =
                new GeneratePresignedUrlRequest(bucketName, key, HttpMethodName.GET);
        // 设置签名过期时间(可选), 若未进行设置, 则默认使用 ClientConfig 中的签名过期时间(1小时)
        // 这里设置签名在半个小时后过期
        Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
        req.setExpiration(expirationDate);
        URL url = cosClient.generatePresignedUrl(req);
        System.out.println(url.toString());

       // 方法2 下载文件到本地的路径，例如 D 盘的某个目录
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
        COSObject cosObject = cosClient.getObject(getObjectRequest);
        COSObjectInputStream cosObjectInput = cosObject.getObjectContent();
        String outputFilePath = key;
        File downFile = new File("D:\\j8\\aa.jpg");
        getObjectRequest = new GetObjectRequest(bucketName, key);
        ObjectMetadata downObjectMeta = cosClient.getObject(getObjectRequest, downFile);
        // 关闭输入流
        try {
            cosObjectInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        cosClient.shutdown();
        resultMap.put("downObjectMeta","下载成功！");
        return resultMap;
    }
}
